from rest_framework import serializers
from goods.models import SKU
from django_redis import get_redis_connection

class CartSKUSerializer(serializers.ModelSerializer):
    """
    购物车商品数据序列化器
    """
    count = serializers.IntegerField(label='数量')

    class Meta:
        model = SKU
        fields = ('id', 'name', 'default_image_url', 'price', 'count')

class PlaceOrderSerializer(serializers.Serializer):

    freight = serializers.DecimalField(label='运费',max_digits=10,decimal_places=2)
    # CartSKUSerializer(skus,many=True)
    skus = CartSKUSerializer(many=True)

from orders.models import OrderInfo, OrderGoods


class OrderCommitSerializer(serializers.ModelSerializer):
    class Meta:
        model = OrderInfo
        fields = ('order_id', 'address', 'pay_method')
        read_only_fields = ('order_id',)
        extra_kwargs = {
            'address': {
                'write_only': True,
                'required': True,
            },
            'pay_method': {
                'write_only': True,
                'required': True
            }
        }
    def create(self, validated_data):

        """
        订单保存
        我们需要先保存订单信息,在保存商品信息

        保存订单信息
        1.获取用户信息
        2.获取地址信息
        3.创建一个order_id
        4.总价格,总数量,运费(初始化,具体计算在保存商品信息中)
        5.支付方式
        6.订单状态
        order = OrderInfo.objects.create()

        保存商品信息
        7.从redis中uoq数据
        hash
        set
        8.获取选中商品的id信息 [sku_id,sku_id]
        9. 根据选中的商品id获取商品信息[SKU,SKU,SKU]
        10.需要对商品列表进行遍历
            11.对商品的库存和销量进行改变
            12.还需要对商品的总结进行累加
            13.保存订单商品数据

        """
        # 1.获取用户信息
        user = self.context['request'].user
        # 2.获取地址信息
        address = validated_data.get('address')
        # 3.创建一个order_id
        # order_id 我们想定义为一个 时间+用户id(规定满足9位) 的数据
        # 　order_id = 201811191719 000000001
        from django.utils import timezone
        order_id = timezone.now().strftime('%Y%m%d%H%M%S%f')+('%09d'%user.id)

        # 4.总价格,总数量,运费(初始化,具体计算在保存商品信息中)
        from decimal import Decimal
        # Decimal 货币类型

        total_amount = Decimal('0')
        total_count = 0
        freight = Decimal('10')

        # 5.支付方式
        pay_method = validated_data.get('pay_method')

        # 6.订单状态  会因为支付方式的不同而不同
        # if pay_method == 1:
        #     #现金,待发货状态
        #     status = 2
        # else:
        #     #支付宝,待支付
        #     status = 1

        if pay_method == OrderInfo.PAY_METHODS_ENUM['CASH']:
            # 现金,待发货状态
            status = OrderInfo.ORDER_STATUS_ENUM['UNSEND']
        else:
            #支付宝,待支付
            status = OrderInfo.ORDER_STATUS_ENUM['UNPAID']

        order = OrderInfo.objects.create(
            user = user,
            order_id = order_id,
            address = address,
            total_amount = total_amount,
            total_count = total_count,
            freight=freight,
            pay_method = pay_method,
            status = status
        )
        # 7.从redis中uoq数据
        redis_conn = get_redis_connection('cart')
        # hash
        sku_id_count = redis_conn.hgetall('cart_%s'%user.id)
        # {1:3,2:3}
        # set
        selected_ids = redis_conn.smembers('cart_selected_%s'%user.id)
        # 对选中商品的id进行遍历,来组织新的数据
        selected_cart = {}
        for sku_id in selected_ids:
            selected_cart[int(sku_id)] = int(sku_id_count[sku_id])

        # 8.获取选中商品的id信息 [sku_id,sku_id]
        ids = selected_cart.keys()
        # 9. 根据选中的商品id获取商品信息[SKU,SKU,SKU]
        skus = SKU.objects.filter(pk__in = ids)

        # 10.需要对商品列表进行遍历
        for sku in skus:
            #用户要购买的数量
            count = selected_cart[sku.id]
            #判断商品的库存是否满足用户购买的数据
            if count > sku.stock:
                raise serializers.ValidationError('库存不足')

            #11.对商品的库存和销量进行改变
            sku.stock -= count
            sku.sales += count
            sku.save()
            #12.还需要对商品的总价格和总数量进行累加
            order.total_count += count
            order.total_amount += (count*sku.price)
            #13.保存订单商品数据
            OrderGoods.objects.create(
                order = order,
                sku = sku,
                count = count,
                price = sku.price
            )
        #保存订单的修改
        order.save()

        return order